﻿using System;
using System.Collections.Generic;
using System.Linq;
using WI.CandidateManager.Common.Data.Entities;

namespace WI.CandidateManager.Business.Objects
{
    /// <summary>
    /// Logic for working with Homeworks: creating, editing, deleting etc.
    /// </summary>
    public class HomeworkBO : BOBase
    {
        #region Homework logic

        /// <summary>
        /// Getting list of own Homeworks
        /// </summary>
        /// <returns>List of own Homeworks</returns>
        public List<Homework> GetHomeworkList()
        {
            try
            {
                if (Session.User.Role == Common.Data.Enums.UserRole.Coach || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {
                    var list = DataContext.HomeworkSet.Where(h => h.Owner.Id == Session.User.Id 
                        && h.State == Common.Data.Enums.State.Active).ToList<Homework>();

                    Logger.Info(String.Format("Try to get list of own homeworks from DB"));
                    return list;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get list of own homeworks from DB"), ex);
                return new List<Homework>();
            }
        }

        /// <summary>
        /// Getting list of all Homeworks
        /// </summary>
        /// <returns>List of all Homeworks</returns>
        public List<Homework> GetAllHomeworkList()
        {
            try
            {
                if (Session.User.Role == Common.Data.Enums.UserRole.Coach || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {
                    var list = DataContext.HomeworkSet.Where(h => h.State == Common.Data.Enums.State.Active).ToList<Homework>();
                    Logger.Info(String.Format("Try to get list of all homeworks from DB"));
                    return list;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get list of all homeworks from DB"), ex);
                return new List<Homework>();
            }
        }

        /// <summary>
        /// Getting list of Pending homeworks.
        /// </summary>
        /// <returns>List of Pending homeworks.</returns>
        public List<Homework> GetPendingTestList()
        {
            try
            {
                var coach = DataContext.CoachSet.Single(c => c.Id == Session.User.Id);

                if (coach.Role == Common.Data.Enums.UserRole.Coach)
                {
                    var list = DataContext.HomeworkSet.Where(h => h.ResultBase.Any(r => r.Status == Common.Data.Enums.TaskState.Completed 
                        && r.Candidate.StudyGroup.Any(g => g.Couch.Any(co => co.Id == coach.Id))
                        && r.State == Common.Data.Enums.State.Active) && h.State == Common.Data.Enums.State.Active).ToList<Homework>();

                    Logger.Info(String.Format("Try to get list of pending homeworks from DB"));
                    return list;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get list of pending homeworks from DB"), ex);
                return new List<Homework>();
            }
        }

        /// <summary>
        /// Get object of Homework.
        /// </summary>
        /// <param name="HomeworkId">Homework id.</param>
        /// <returns>Object of Homework.</returns>
        public Homework GetHomework(long HomeworkId)
        {
            try
            {
                var homework = DataContext.HomeworkSet.Single(h => h.Id == HomeworkId);
                Logger.Info(String.Format("Try to get homework by HomeworkId={0} from DB", HomeworkId));
                return homework;
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get homework by HomeworkId={0} from DB", HomeworkId), ex);
                return null;
            }
        }

        /// <summary>
        /// Create new Homework and add it to DataBase.
        /// </summary>
        /// <param name="homework">Object of Homework from controller.</param>
        /// <returns>True if creating was succesful and false if it wasn't.</returns>
        public bool CreateNewHomework(Homework homework)
        {
            try
            {
                var curUser = DataContext.CoachSet.Where(c => c.Id == Session.User.Id).Single();

                if (curUser.Role == Common.Data.Enums.UserRole.Coach || curUser.Role == Common.Data.Enums.UserRole.Admin)
                {
                    homework.Owner = curUser;
                    homework.CreateDate = System.DateTime.Now;

                    DataContext.HomeworkSet.Add(homework);
                    DataContext.SaveChanges();
                    Logger.Info(String.Format("Try to create new homework in DB"));
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to create new homework in DB"), ex);
                return false;
            }
        }

        /// <summary>
        /// Change object of Homework.
        /// </summary>
        /// <param name="HomeworkId">Homework id.</param>
        /// <param name="homework">Object of Homework.</param>
        /// <returns>True if editing was succesful and false if it wasn't.</returns>
        public bool ChangeHomework(long HomeworkId, Homework homework)
        {
            try
            {
                var curHomework = DataContext.HomeworkSet.Where(h => h.Id == HomeworkId).Single();

                if (curHomework.Owner.Id == Session.User.Id || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {

                    curHomework.Name = homework.Name;
                    curHomework.Description = homework.Description;
                    curHomework.State = homework.State;

                    DataContext.Entry(curHomework).State = System.Data.EntityState.Modified;
                    Logger.Info(String.Format("Try to change homework (HomeworkId={0}) in DB", HomeworkId));
                    DataContext.SaveChanges();
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to change homework (HomeworkId={0}) in DB", HomeworkId), ex);
                return false;
            }
        }

        /// <summary>
        /// Delete object of Homework.
        /// </summary>
        /// <param name="HomeworkId">Homework id.</param>
        /// <returns>True if deleting was succesful and false if it wasn't.</returns>
        public bool DeleteHomework(long HomeworkId)
        {
            try
            {
                var homework = DataContext.HomeworkSet.Single(h => h.Id == HomeworkId);

                if (homework.Owner.Id == Session.User.Id || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {
                    homework.State = Common.Data.Enums.State.Deleted;       
                    DataContext.SaveChanges();
                    Logger.Info(String.Format("Try to delete homework (HomeworkId={0}) from DB", HomeworkId));

                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to delete homework (HomeworkId={0}) from DB", HomeworkId), ex);
                return false;
            }
        }

        #endregion
    }
}
